﻿using Mapster;
using Shop.Core.Helper;
using Shop.Core.Repository;
using Shop.Core.Share;
using Shop.IServices;
using Shop.Model.Dto.User;
using Shop.Model.Entity.Use;
using Shop.Model.View.Use;

namespace Shop.Services
{
    /// <summary>
    /// 收货地址服务
    /// </summary>
    public class AddressAppService : IAddressAppService
    {
        private readonly IUserContext _userContext;

        private RepositoryBase<UserAddress> _addressRepository;

        public AddressAppService(IUserContext userContext
            , RepositoryBase<UserAddress> addressRepository)
        {
            _userContext = userContext;
            _addressRepository = addressRepository;
        }

        /// <summary>
        /// 添加收货地址
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<bool> CreateAsync(AddressAddDto input)
        {
            if (input.IsDefault)
                await _addressRepository.UpdateAsync(x => new UserAddress { IsDefault = false}, x => x.UserId == _userContext.Id && x.IsDefault == true);
            var address = input.Adapt<UserAddress>();
            address.UserId = _userContext.Id;
            await _addressRepository.InsertAsync(address);
            return true;
        }

        /// <summary>
        /// 删除地址
        /// </summary>
        /// <param name="Id"></param>
        /// <returns></returns>
        public async Task<bool> DeleteAsync(long Id)
        {
            var address = await _addressRepository.GetByIdAsync(Id);
            if (address == null || address.UserId != _userContext.Id)
                return false;
            return await _addressRepository.DeleteByIdAsync(Id);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="UserId"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<List<AddressVo>> ListAsync()
        {
            return await _addressRepository.Where(x => x.UserId == _userContext.Id)
                .OrderByDescending(x => x.IsDefault)
                .Select(x => new AddressVo {
                    Id = x.Id,
                    Name = x.Name,
                    Telephone = x.Telephone,
                    Detail = x.Detail,
                    ProvinceCode = x.ProvinceCode,
                    Province = x.Province,
                    CityCode = x.CityCode,
                    City = x.City,
                    DistrictCode = x.DistrictCode,
                    District = x.District,
                    StreetCode = x.StreetCode,
                    Street = x.Street,
                    IsDefault = x.IsDefault,
                })
                .ToListAsync();
        }

        /// <summary>
        /// 更新收货地址
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<bool> UpdateAsync(AddressModifyDto input)
        {
            var address = await _addressRepository.GetByIdAsync(input.Id);
            if (address == null || address.UserId != _userContext.Id)
                return false;
            //将该地址设为默认地址时，需要把其它地址设为非默认地址
            if (!address.IsDefault && input.IsDefault)
                await _addressRepository.UpdateAsync(x => new UserAddress { IsDefault = false} , x => x.UserId == _userContext.Id && x.IsDefault == true);

            address.ProvinceCode = input.ProvinceCode;
            address.Province = input.Province;
            address.CityCode = input.CityCode;
            address.City = input.City;
            address.DistrictCode = input.DistrictCode;
            address.District = input.District;
            address.StreetCode = input.StreetCode;
            address.Street = input.Street;
            address.Detail = input.Detail;
            address.Name = input.Name;
            address.Telephone = input.Telephone;
            address.IsDefault = input.IsDefault;
            return await _addressRepository.UpdateAsync(address);
        }
    }
}
